/***********************************************
 **** 版权声明处 **
 ****  为了方便阅读和维护，请严格遵守相关代码规范，谢谢   ****
 *******************************************/
package bpm.graphic
{
	/*******************************************
	 **** huangjixin,2012-10-23,上午10:38:18 **
	 **** 请一句话表述该类主要作用  **
	 *******************************************/
	import bpm.graphic.decorators.DecoratorPlayer;
	import bpm.graphic.events.DiagramEditorEvent;
	import bpm.graphic.skins.ResizeAdornerSkin;
	
	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	import mx.core.FlexGlobals;
	import mx.core.IVisualElement;
	import mx.core.IVisualElementContainer;
	
	import spark.components.supportClasses.SkinnableComponent;
	
	public class ResizeAdorner extends SkinnableComponent
	{
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// private 类私有静态变量和静态常量声明处。（全部大写，使用下划线进行分割）
		// 例如：private static const EXAMPLE:String = "example";
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// public 类公有静态变量和静态常量声明处。（全部大写，使用下划线进行分割）
		// 例如：public static const EXAMPLE:String = "example";
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		
		
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// private 私有变量声明处，请以“_”开头定义变量
		// 例如：private var _example:String;
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		private var _adornedObject : Render;
		
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// public 公有变量声明处
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		
		[SkinPart]
		public var bottomLeftHandle:Handle;
		[SkinPart]
		public var bottomRightHandle:Handle;
		[SkinPart]
		public var topLeftHandle:Handle;
		[SkinPart]
		public var topRightHandle:Handle;
		[SkinPart]
		public var CENTER:Port;
		[SkinPart]
		public var LEFT:Port;
		[SkinPart]
		public var RIGHT:Port;
		[SkinPart]
		public var TOP:Port;
		[SkinPart]
		public var BOTTOM:Port;
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// 构造函数，初始化相关工作可以放在里面
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		private var _rect:Rectangle = new Rectangle();
		private var _startPoint:Point = new Point();
		private var _pressHandle:DisplayObject;
		
		private var point:Point = new Point();
		
		public function ResizeAdorner(adornedObject:Render)
		{
			super();
			this.adornedObject = adornedObject;
			setStyle("skinClass",ResizeAdornerSkin);
			
			play();
		}//构造函数结束
		
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// getter和setter函数
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		
		public function get pressHandle():DisplayObject
		{
			return _pressHandle;
		}

		public function set pressHandle(value:DisplayObject):void
		{
			_pressHandle = value;
		}

		[Bindable]
		public function get adornedObject():Render
		{
			return _adornedObject;
		}

		public function set adornedObject(value:Render):void
		{
			_adornedObject = value;
		}
		
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// 相关事件响应函数和逻辑函数存放处
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		
		protected function onAdornerObjectMove(event:MouseEvent):void
		{
			if(!this.adornedObject){
				return;
			}
			this.width = this.adornedObject.width;
			this.height = this.adornedObject.height;
			var point:Point = new Point();
			point = this.adornedObject.localToGlobal(point);
			point = FlexGlobals.topLevelApplication.globalToLocal(point);
			if(!FlexGlobals.topLevelApplication.contains(this)){
				FlexGlobals.topLevelApplication.addElement(this);
			}
			
			this.x = point.x;
			this.y = point.y;
		}
		
		public function play():void
		{
			this.width = this.adornedObject.width;
			this.height = this.adornedObject.height;
			var point:Point = new Point();
			point = this.adornedObject.localToGlobal(point);
			point = FlexGlobals.topLevelApplication.globalToLocal(point);
			if(!FlexGlobals.topLevelApplication.contains(this)){
				FlexGlobals.topLevelApplication.addElement(this);
			}
			
			this.x = point.x;
			this.y = point.y;
			
			this.adornedObject.stage.addEventListener(MouseEvent.MOUSE_MOVE,onAdornerObjectMove);
			this.adornedObject.addEventListener(DiagramEditorEvent.EDITOR_DELETE, onEditorDelete);
		}//play结束
		
		public function cleanUp(resizeAdorner:ResizeAdorner):void{
			if(!this.adornedObject){
				return;
			}
			if(!this.adornedObject.stage){
				return;
			}
			this.adornedObject.stage.removeEventListener(MouseEvent.MOUSE_MOVE,onAdornerObjectMove);
			this.adornedObject.removeEventListener(DiagramEditorEvent.EDITOR_DELETE, onEditorDelete);
			if(FlexGlobals.topLevelApplication.contains(resizeAdorner)){
				FlexGlobals.topLevelApplication.removeElement(resizeAdorner);
			}
			
		}
		
		protected function onEditorDelete(event:Event):void
		{
			cleanUp(this);
			this.adornedObject = null;
		}
		
		protected function onHandleMouseDown(event:MouseEvent):void
		{
			event.stopImmediatePropagation();
			handlePressed(event.currentTarget as DisplayObject, event);
		}
		
		
		protected function handlePressed(handle:DisplayObject, event:MouseEvent):void{
			DecoratorPlayer.draggingResizeAdorner = true;
			
			pressHandle = handle as Handle;
			this._startPoint.x = mouseX;
			this._startPoint.y = mouseY;
			this._startPoint  = this.localToGlobal(_startPoint);
			
			_rect.x = this._startPoint.x;
			_rect.y = this._startPoint.y;
			_rect.width = adornedObject.width;
			_rect.height = adornedObject.height;
			
			FlexGlobals.topLevelApplication.parent.addEventListener(MouseEvent.MOUSE_MOVE,onHandleMouseMove);
			FlexGlobals.topLevelApplication.parent.addEventListener(MouseEvent.MOUSE_UP,onHandlerMouseUp);
		}
		
		protected function onHandleMouseMove(event:MouseEvent):void
		{
			
			var xPlus:Number = FlexGlobals.topLevelApplication.parent.mouseX - this._startPoint.x;            
			var yPlus:Number = FlexGlobals.topLevelApplication.parent.mouseY - this._startPoint.y;
			
			if(pressHandle == bottomRightHandle){
				adornedObject.width  = this._rect.width + xPlus < _pressHandle.width * 2 ? _pressHandle.width * 2 : this._rect.width + xPlus;
				adornedObject.height = this._rect.height+ yPlus < _pressHandle.height * 2 ? _pressHandle.height * 2 : this._rect.height + yPlus;
			}else if(_pressHandle == topLeftHandle){
				point.x = FlexGlobals.topLevelApplication.parent.mouseX;
				point.y = FlexGlobals.topLevelApplication.parent.mouseY;
				point =  adornedObject.parent.globalToLocal(point);
				adornedObject.x = point.x;
				adornedObject.y = point.y;
				adornedObject.width  = _rect.width - xPlus < _pressHandle.width * 2 ? _pressHandle.width * 2 : _rect.width - xPlus;
				adornedObject.height  = _rect.height -yPlus < _pressHandle.height * 2 ? _pressHandle.height * 2 : this._rect.height - yPlus;
			}else if(pressHandle == topRightHandle){
				point.x = FlexGlobals.topLevelApplication.parent.mouseX;
				point.y = FlexGlobals.topLevelApplication.parent.mouseY;
				point =  adornedObject.parent.globalToLocal(point);
				adornedObject.y = point.y;
				adornedObject.width  = this._rect.width + xPlus < _pressHandle.width * 2 ? _pressHandle.width * 2 : this._rect.width + xPlus;
				adornedObject.height  = _rect.height -yPlus < _pressHandle.height * 2 ? _pressHandle.height * 2 : this._rect.height - yPlus;
			}else if(pressHandle == bottomLeftHandle){
				point.x = FlexGlobals.topLevelApplication.parent.mouseX;
				point.y = FlexGlobals.topLevelApplication.parent.mouseY;
				point =  adornedObject.parent.globalToLocal(point);
				adornedObject.x = point.x;
				adornedObject.width  = _rect.width - xPlus < _pressHandle.width * 2 ? _pressHandle.width * 2 : _rect.width - xPlus;
				adornedObject.height  = this._rect.height+ yPlus < _pressHandle.height * 2 ? _pressHandle.height * 2 : this._rect.height + yPlus;
			}
			
		}
		
		protected function onHandlerMouseUp(event:Event):void
		{
			DecoratorPlayer.draggingResizeAdorner = false;
			pressHandle = null;
			FlexGlobals.topLevelApplication.parent.removeEventListener(MouseEvent.MOUSE_MOVE,onHandleMouseMove);
			FlexGlobals.topLevelApplication.parent.removeEventListener(MouseEvent.MOUSE_UP,onHandlerMouseUp);
		}
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// override 覆盖函数
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

		override protected function partRemoved(partName:String, instance:Object):void{
			super.partRemoved(partName,instance);
			
			if(instance == bottomLeftHandle){
				bottomLeftHandle.removeEventListener(MouseEvent.MOUSE_DOWN,onHandleMouseDown);
			}
			if(instance == bottomRightHandle){
				bottomRightHandle.removeEventListener(MouseEvent.MOUSE_DOWN,onHandleMouseDown);
			}
			if(instance == topLeftHandle){
				topLeftHandle.removeEventListener(MouseEvent.MOUSE_DOWN,onHandleMouseDown);
			}
			if(instance == topRightHandle){
				topRightHandle.removeEventListener(MouseEvent.MOUSE_DOWN,onHandleMouseDown);
			}
			var index:int = -1;
			if(instance == CENTER){
				index = adornedObject.ports.getItemIndex(CENTER);
				if(index!=-1){
					adornedObject.ports.removeItemAt(index);
				}
			}
			if(instance == LEFT){
				index = adornedObject.ports.getItemIndex(LEFT);
				if(index!=-1){
					adornedObject.ports.removeItemAt(index);
				}
			}
			if(instance == RIGHT){
				index = adornedObject.ports.getItemIndex(RIGHT);
				if(index!=-1){
					adornedObject.ports.removeItemAt(index);
				}
			}
			if(instance == TOP){
				index = adornedObject.ports.getItemIndex(TOP);
				if(index!=-1){
					adornedObject.ports.removeItemAt(index);
				}
			}
			if(instance == BOTTOM){
				index = adornedObject.ports.getItemIndex(BOTTOM);
				if(index!=-1){
					adornedObject.ports.removeItemAt(index);
				}
			}
		}
		
		override protected function partAdded(partName:String, instance:Object):void{
			super.partAdded(partName,instance);
			
			if(instance == bottomLeftHandle){
				bottomLeftHandle.addEventListener(MouseEvent.MOUSE_DOWN,onHandleMouseDown);
			}
			if(instance == bottomRightHandle){
				bottomRightHandle.addEventListener(MouseEvent.MOUSE_DOWN,onHandleMouseDown);
			}
			if(instance == topLeftHandle){
				topLeftHandle.addEventListener(MouseEvent.MOUSE_DOWN,onHandleMouseDown);
			}
			if(instance == topRightHandle){
				topRightHandle.addEventListener(MouseEvent.MOUSE_DOWN,onHandleMouseDown);
			}
			if(instance == CENTER){
				adornedObject.ports.addItem(CENTER);
				CENTER.ownerObject = this.adornedObject;
			}
			if(instance == LEFT){
				adornedObject.ports.addItem(LEFT);
				LEFT.ownerObject = this.adornedObject;
			}
			if(instance == RIGHT){
				adornedObject.ports.addItem(RIGHT);
				RIGHT.ownerObject = this.adornedObject;
			}
			if(instance == TOP){
				adornedObject.ports.addItem(TOP);
				TOP.ownerObject = this.adornedObject;
			}
			if(instance == BOTTOM){
				adornedObject.ports.addItem(BOTTOM);
				BOTTOM.ownerObject = this.adornedObject;
			}
		}
	}//类结束
}//包结束